import datetime
import json
import os
import sys
from smart_open import open
import boto3

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from project_utils.mysql_conncet import ReadFromMysql
from config import *
from aws_model.aws_stepfunc import send_task_failure, send_task_success
from base_class.inspect_logging import print_to_log
from aws_model.athena_submit import submit

rds_mysql = ReadFromMysql(host=mysqlhost, user=user, password=password, port=3306)
rds_mysql.makepool("air_bigdata")
ac365_mysql = ReadFromMysql(host=ac365_mysqlhost, user=ac365_user, password=ac365_password, port=3306)
ac365_mysql.makepool("elecard")
s3 = boto3.client("s3")


# 执行导入程序
def run(start="", end=""):
    # 如果没有指定日期，则读取上一次记录的增量时间
    if not (start and end):
        time_rs = rds_mysql.read_from_mysql("select lasttime from ac365_time order by id desc limit 1")
        if len(time_rs) > 0:
            increment_time = time_rs[0]["lasttime"]
            ac365_rs = ac365_mysql.read_from_mysql(
                f"select max(create_time) as last_time from ac365 where create_time>'{increment_time}'")
            start = increment_time + datetime.timedelta(seconds=1)
            end = ac365_rs[0]["last_time"]
        # 没有上一次时间 代表第一次导入
        else:
            ac365_rs = ac365_mysql.read_from_mysql(
                "select min(create_time) as first_time,max(create_time) as last_time from ac365")
            start = ac365_rs[0]["first_time"]
            end = ac365_rs[0]["last_time"]
    else:
        start = datetime.datetime.strptime(start, '%Y-%m-%d %H:%M:%S')
        end = datetime.datetime.strptime(end, '%Y-%m-%d %H:%M:%S')
    # 将时间分割为1天为单位
    if start and end:
        times = split_time(start, end)
        # 每天单独导入一次
        for i in times:
            sql = f"select * from ac365 where create_time>='{i[0]}' and create_time <= '{i[1]}' "
            rs = ac365_mysql.read_from_mysql(sql)
            print("执行sql:", sql, ",结果数量:", len(rs))
            write_to_s3(str(i[1]), rs)
            # print(rs)
        rds_mysql.read_from_mysql(f"insert into ac365_time(lasttime) values('{end}')")
    output = {"msg": f"导入ac365成功,最新时间戳更新为{end}", "Payload": {}}
    output = json.dumps(output)
    step_response = send_task_success(tasktoken, output)
    print_to_log("step_response: ", step_response)


# 写入S3
def write_to_s3(date, rs):
    # 有数据才写入
    if len(rs) > 0:
        file_name = f"{ac365_location}/p_date={date[0:10]}/{date}-{datetime.datetime.now().timestamp()}.json.gz"
        # 使用smart-open框架写入S3
        # session = boto3.Session(region_name=FORMAL_S3_CONFIG['region_name'],
        #                         aws_access_key_id=FORMAL_S3_CONFIG["access_key"],
        #                         aws_secret_access_key=FORMAL_S3_CONFIG["secret_key"])
        transport_params = {'client': s3}

        # 写出通道
        with open(file_name, 'w', compression='.gz', encoding='utf-8', transport_params=transport_params) as fw:
            length = len(rs)
            for i in range(0, length):
                one = rs[i]
                for key in one:
                    one[key] = str(one[key])
                if i == length - 1:
                    fw.write(json.dumps(one, ensure_ascii=False))
                else:
                    fw.write(json.dumps(one, ensure_ascii=False) + "\n")
        print("写入文件" + file_name + "成功")
        submit(f"alter table original.ac_ac365_daily add  if not exists  partition(p_date = '{date[0:10]}')")


# 分割时间为一天一天格式
def split_time(start, end):
    list = []
    tmp = start + datetime.timedelta(days=1)
    mid = datetime.datetime(year=tmp.year, month=tmp.month, day=tmp.day)
    while True:
        if mid < end:
            list.append([start, str(mid - datetime.timedelta(seconds=1))])
            start = mid
            tmp = start + datetime.timedelta(days=1)
            mid = datetime.datetime(year=tmp.year, month=tmp.month, day=tmp.day)
        else:
            list.append([start, end])
            break
    return list


if __name__ == '__main__':
    try:
        event = json.loads(sys.argv[1])
        tasktoken = event.get('TaskToken')
        if "start" in event:
            run(event['start'], event['end'])
        else:
            run()
    except Exception as e:
        print_to_log("任务失败")
        print_to_log("原因： ", str(e))
        send_task_failure(str(e), str(e), tasktoken)
